當一個陣列B的長度是等於另一個變數A裡的值。不做額外處理的話,必須隨時注意A與B是否相同。為了方便及穩定性,不彷自訂一個class包含變數變數A與陣列B,並為此class訂做一個PropertyDrawer,如此一來,既自動又正確。先附上圖說明before與After。
範例目標 (MeshRenderer上的Materials有幾個,陣列長度就是多少)
Before (指定完MeshRenderer後,還需要指定陣列長度)
After (指定完MeshRenderer後,自動根據Materials初始化陣列)
範例程式碼 (Sample.cs)
using System;
using UnityEngine;
public enum State { _1, _2, _3 }
// Custom serializable class
[Serializable]
public class Table
{
public MeshRenderer meshRenderer;
public State[] states;
}
public class Sample : MonoBehaviour
{
public Table table;
}
範例程式碼 (TableDrawer.cs)
using UnityEditor;
using UnityEngine;
[CustomPropertyDrawer(typeof(Table))]
public class TableDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
Rect rLabel = position;
Rect rField = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
rField.height = EditorGUIUtility.singleLineHeight;
SerializedProperty spMesh = property.FindPropertyRelative("mesh");
SerializedProperty spStates = property.FindPropertyRelative("states");
EditorGUI.PropertyField(rField, spMesh, GUIContent.none);
rField.y += EditorGUIUtility.singleLineHeight;
MeshRenderer mesh = spMesh.objectReferenceValue as MeshRenderer;
if (mesh != null && mesh.sharedMaterials.Length > 0)
{
spStates.arraySize = mesh.sharedMaterials.Length;
for (int i = 0; i < spStates.arraySize; ++i)
{
SerializedProperty spLipShape = spStates.GetArrayElementAtIndex(i);
string labelName = " " + mesh.sharedMaterials[i].name;
Rect rt = new Rect(rLabel.x, rField.y, rLabel.width - rField.width, rLabel.height);
EditorGUI.LabelField(rt, labelName);
EditorGUI.PropertyField(rField, spLipShape, GUIContent.none);
rField.y += EditorGUIUtility.singleLineHeight;
}
}
EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
int lineCount = 1;
SerializedProperty spMesh = property.FindPropertyRelative("mesh");
MeshRenderer mesh = spMesh.objectReferenceValue as MeshRenderer;
if (mesh != null) lineCount += mesh.sharedMaterials.Length;
return EditorGUIUtility.singleLineHeight * lineCount;
}
}